home *** CD-ROM | disk | FTP | other *** search
/ Mac Power 1997 December / MACPOWER-1997-12.ISO.7z / MACPOWER-1997-12.ISO / AMUG / PROGRAMMING / Raven 1.2 Examples.sit / Raven 1.2 Examples / Quill / Source / CustomClasses.cpp < prev    next >
Text File  |  1997-09-03  |  7KB  |  283 lines

  1. /*
  2.  *  File:       CustomClasses.cpp
  3.  *  Summary:       A class containing information about custom pane classes.
  4.  *  Written by: Jesse Jones
  5.  *
  6.  *  Copyright ゥ 1996-1997 Jesse Jones. 
  7.  *    For conditions of distribution and use, see copyright notice in ZTypes.h  
  8.  *
  9.  *  Change History (most recent first):    
  10.  *
  11.  *         <2>     4/26/97    JDJ        Added GetCreator.
  12.  *         <1>    10/14/96    JDJ        Created
  13.  */
  14.  
  15. #include "CustomClasses.h"
  16.  
  17. #include <Map.h>
  18. #include <Resources.h>
  19.  
  20. #include <ZApplication.h>
  21. #include <ZDialogBox.h>
  22. #include <ZDialogHandler.h>
  23. #include <ZExceptions.h>
  24. #include <ZHandleStream.h>
  25. #include <ZInput.h>
  26. #include <ZLocker.h>
  27. #include <ZResUtils.h>
  28. #include <ZTextBox.h>
  29.  
  30.  
  31. // ===================================================================================
  32. //    Internal Functions
  33. // ===================================================================================
  34.  
  35. //---------------------------------------------------------------
  36. //
  37. // GetClassName
  38. //
  39. //---------------------------------------------------------------
  40. static string GetClassName(const string& oldName)
  41. {
  42.     TDialogBox* dialog = TDialogBox::Create(207, TApplication::Instance());
  43.     
  44.     TTextBox* textBox = dynamic_cast<TTextBox*>(dialog->FindSubPane("Class Name"));
  45.     textBox->SetText(oldName);
  46.     textBox->SelectAll();
  47.     
  48.     dialog->SetLatentTarget(textBox);
  49.  
  50.     string message = kNothingMessage;
  51.     
  52.     {
  53.     TDialogHandler handler(dialog);
  54.         dialog->Show();
  55.     
  56.         while (message != kOKMessage)
  57.             message = handler.ProcessNextEvent();
  58.     }
  59.     
  60.     string name = textBox->GetText();
  61.     
  62.     return name;
  63. }
  64.  
  65. #pragma mark -
  66.  
  67. // ===================================================================================
  68. //    class CCustomClasses
  69. // ===================================================================================
  70.  
  71. //---------------------------------------------------------------
  72. //
  73. // CCustomClasses::~CCustomClasses
  74. //
  75. //---------------------------------------------------------------
  76. CCustomClasses::~CCustomClasses()
  77. {
  78.     delete mTable;
  79. }
  80.  
  81.  
  82. //---------------------------------------------------------------
  83. //
  84. // CCustomClasses::CCustomClasses
  85. //
  86. //---------------------------------------------------------------
  87. CCustomClasses::CCustomClasses()
  88. {
  89.     mTable = new ClassTable;
  90. }
  91.  
  92.  
  93. //---------------------------------------------------------------
  94. //
  95. // CCustomClasses::GetNumClasses
  96. //
  97. //---------------------------------------------------------------
  98. long CCustomClasses::GetNumClasses() const
  99. {
  100.     return mTable->size();
  101. }
  102.  
  103.  
  104. //---------------------------------------------------------------
  105. //
  106. // CCustomClasses::HasClass
  107. //
  108. //---------------------------------------------------------------
  109. bool CCustomClasses::HasClass(const string& derivedClass) const
  110. {
  111.     ClassTable::const_iterator iter = mTable->find(derivedClass);
  112.     
  113.     return !(iter == mTable->end());        // CW Pro 1 has problems finding operator!= when precompiling SGI STL
  114. }
  115.  
  116.  
  117. //---------------------------------------------------------------
  118. //
  119. // CCustomClasses::GetBaseClass
  120. //
  121. //---------------------------------------------------------------
  122. string CCustomClasses::GetBaseClass(const string& derivedClass) const
  123. {
  124.     string baseClass;
  125.     
  126.     ClassTable::const_iterator iter = mTable->find(derivedClass);
  127.     
  128.     if (!(iter == mTable->end()))            // CW Pro 1 has problems finding operator!= when precompiling SGI STL
  129.         baseClass = (*iter).second;
  130.     else
  131.         throw TDomainException(derivedClass + LoadAppString(" isn't one of the known custom types."));
  132.         
  133.     return baseClass;
  134. }
  135.     
  136.  
  137. //---------------------------------------------------------------
  138. //
  139. // CCustomClasses::AddClass
  140. //
  141. //---------------------------------------------------------------
  142. void CCustomClasses::AddClass(const string& derivedClass, const string& baseClass)
  143. {
  144.     ClassTable::iterator iter = mTable->find(derivedClass);
  145.     
  146.     if (iter == mTable->end()) {
  147.         mTable->insert(ClassEntry(derivedClass, baseClass));
  148.         
  149.         CreatorProcPtr creator = this->GetCreator(baseClass);
  150.  
  151.         TReanimator::Instance()->UnregisterClass(derivedClass);
  152.         TReanimator::Instance()->RegisterClass(derivedClass, creator);
  153.  
  154.         this->Broadcast(this);
  155.         
  156.     } else {
  157.         ClassEntry& entry = *iter;
  158.         
  159.         if (entry.second != baseClass) {
  160.             entry.second = baseClass;
  161.  
  162.             CreatorProcPtr creator = this->GetCreator(baseClass);
  163.  
  164.             TReanimator::Instance()->UnregisterClass(derivedClass);
  165.             TReanimator::Instance()->RegisterClass(derivedClass, creator);
  166.  
  167.             this->Broadcast(this);
  168.         }
  169.     }
  170. }
  171.  
  172.  
  173. //---------------------------------------------------------------
  174. //
  175. // CCustomClasses::RemoveClass
  176. //
  177. // Note that we do not unregister the derived class because other
  178. // documents may still be using it.
  179. //
  180. //---------------------------------------------------------------
  181. void CCustomClasses::RemoveClass(const string& derivedClass)
  182. {
  183.     ASSERT(mTable->count(derivedClass) == 1);
  184.  
  185.     mTable->erase(derivedClass);
  186.  
  187.     this->Broadcast(this);
  188. }
  189.  
  190.  
  191. //---------------------------------------------------------------
  192. //
  193. // CCustomClasses::ReadResources
  194. //
  195. //---------------------------------------------------------------
  196. void CCustomClasses::ReadResources()
  197. {
  198.     this->DisableBroadcasting();
  199.     
  200.     // Zap any old names that may be hanging around
  201.     while (mTable->size() > 0) {
  202.         ClassTable::iterator iter = mTable->begin();
  203.         
  204.         this->RemoveClass((*iter).first);
  205.     }
  206.  
  207.     // and read in the new resources.
  208.     short num = ::Count1Resources(kType);
  209.     ASSERT(num <= 1);
  210.     
  211.     for (short index = 1; index <= num; index++) {
  212.         Handle hand = ::Get1IndResource(kType, index);
  213.         ThrowIfResFail(hand);
  214.         
  215.         TInHandleStream stream(hand);                    // stream takes the handle
  216.         while (!stream.AtEnd()) {
  217.             string derived, base;
  218.             
  219.             stream >> derived >> base;
  220.             
  221.             this->AddClass(derived, base);
  222.         }
  223.     }
  224.  
  225.     this->EnableBroadcasting();
  226.     this->Broadcast(this);
  227. }
  228.  
  229.  
  230. //---------------------------------------------------------------
  231. //
  232. // CCustomClasses::WriteResources
  233. //
  234. // ・・・ハrewrite this so that an error while writing the new data
  235. // ・・・ハout doesn't trash all of the old data
  236. //
  237. //---------------------------------------------------------------
  238. void CCustomClasses::WriteResources(ResID id)
  239. {
  240.     // Out with the old...
  241.     Delete1Resource(kType);
  242.  
  243.     // and in with the new.
  244.     TOutHandleStream stream;
  245.     ClassTable::iterator iter = mTable->begin();
  246.     while (iter != mTable->end()) {
  247.         ClassEntry& entry = *iter++;
  248.     
  249.         stream << entry.first << entry.second;
  250.     }
  251.     
  252.     {
  253.     THandle hand = stream.GetHandle();    
  254.     TLocker lock(hand);
  255.         WriteResource(kType, id, hand.GetPtr(), hand.GetSize());
  256.     }
  257. }
  258.  
  259. #pragma mark ハ
  260.  
  261. //---------------------------------------------------------------
  262. //
  263. // CCustomClasses::GetCreator
  264. //
  265. //---------------------------------------------------------------
  266. CreatorProcPtr CCustomClasses::GetCreator(const string& className)
  267. {
  268.     CreatorProcPtr creator = nil;
  269.  
  270.     try {
  271.         creator = TReanimator::Instance()->GetCreator(className);
  272.         
  273.     } catch (const TReanimateException& e) {
  274.         string name = ::GetClassName(className);
  275.  
  276.         creator = TReanimator::Instance()->GetCreator(name);
  277.     }    
  278.     
  279.     return creator;
  280. }
  281.  
  282.  
  283.